りおんクロニクル


>SQLite × ローカルDB → サーバー同期|オフライン対応アプリの完全ガイド【2026年版】

Home【2026年版】C# / .NET入門と実践ガイド|基礎・業務アプリ開発・SQLite連携まで体系的に解説

製造現場・営業端末・モバイルアプリなど、 「ネットが不安定でも動くアプリ」は今や必須です。 その中心となるのが、ローカルSQLite → サーバーDBの同期設計。 しかし、同期は単なる「アップロード・ダウンロード」ではなく、 差分管理・競合解決・キュー化・API設計など多くの要素が絡みます。

この記事でわかること
・ローカルDBとサーバーDBの同期モデル
・差分同期の仕組み(UpdatedAt / Version)
・競合解決のパターン
・送信キュー(アウトボックス)方式
・API設計(Pull / Push)
・業務アプリ向けの実務アーキテクチャ

1. オフライン対応アプリの基本構造

オフライン対応アプリは、次の3層で構成されます。

  1. ローカルDB(SQLite):アプリが直接読み書き
  2. 同期キュー(送信バッファ):変更履歴を蓄積
  3. サーバーAPI:Pull(取得)/ Push(送信)

この構造にすることで、ネットが切れてもアプリは動き続け、 オンラインに戻った瞬間に同期が走ります。

2. 差分同期の基本:UpdatedAt(タイムスタンプ)方式

最もシンプルで実務的なのが、 UpdatedAt(最終更新日時)を使った差分同期です。

■ テーブル例(ローカル・サーバー共通)

CREATE TABLE Users (
    Id         TEXT PRIMARY KEY,
    Name       TEXT NOT NULL,
    Age        INTEGER,
    UpdatedAt  TEXT NOT NULL,  -- ISO8601 UTC
    IsDeleted  INTEGER NOT NULL DEFAULT 0
);

■ UpdatedAt の役割

3. ローカル → サーバー同期(Push)の仕組み

ローカルで変更されたデータを、 送信キュー(アウトボックス)に記録しておき、 ネット復帰時にまとめてサーバーへ送信します。

■ アウトボックステーブル例

CREATE TABLE Outbox (
    Id         INTEGER PRIMARY KEY AUTOINCREMENT,
    Entity     TEXT NOT NULL,     -- Users / Orders など
    EntityId   TEXT NOT NULL,
    Payload    TEXT NOT NULL,     -- JSONで変更内容
    CreatedAt  TEXT NOT NULL
);

■ ローカル更新時の処理

UPDATE Users SET Name = @name, UpdatedAt = @now WHERE Id = @id;

INSERT INTO Outbox (Entity, EntityId, Payload, CreatedAt)
VALUES ('Users', @id, @json, @now);

これにより、ネットが無くても変更履歴が蓄積されます。

■ サーバー送信(Push API)

POST /sync/push
[
  {
    "Entity": "Users",
    "EntityId": "U001",
    "Payload": { "Name": "Taro", "UpdatedAt": "2026-04-04T09:00:00Z" }
  }
]

■ サーバー側の処理

4. サーバー → ローカル同期(Pull)の仕組み

サーバー側の更新をローカルに反映するには、 「前回同期日時」以降の更新だけ取得します。

■ Pull API例

GET /sync/pull?since=2026-04-04T08:00:00Z

■ サーバーのレスポンス例

[
  { "Id": "U001", "Name": "Taro", "UpdatedAt": "2026-04-04T09:00:00Z" },
  { "Id": "U002", "Name": "Hanako", "UpdatedAt": "2026-04-04T09:10:00Z" }
]

■ ローカル側の反映

if (server.UpdatedAt > local.UpdatedAt)
{
    UPDATE Users SET ...;
}

これで差分だけ高速に同期できます。

5. 競合解決(Conflict Resolution)

ローカルとサーバーが同じデータを別々に更新した場合、 どちらを採用するかを決める必要があります。

■ よくある競合解決ポリシー

方式説明用途
Last Write WinsUpdatedAt が新しい方を採用最もシンプル
Server Wins常にサーバー側を優先マスタデータ
Client Winsローカル側を優先現場入力を重視
Mergeフィールドごとにマージ複雑な業務

多くの業務アプリでは、 Last Write Wins(最終更新優先)が採用されます。

6. 同期の実行タイミング

同期は次のタイミングで行うのが一般的です。

特にネットワーク復帰時の自動同期はUXが良くなります。

7. セキュリティ:同期APIは必ず保護する

同期APIはデータの出入口なので、 認証・認可・暗号化が必須です。

■ 必須対策

8. 実務アーキテクチャ(完成形)

■ 全体構成図(文章版)

9. 業務アプリ向けベストプラクティス

まとめ:SQLite × サーバー同期は“差分・キュー・競合解決”が鍵

「ネットが不安定でも動くアプリ」は、 現場での信頼性を大きく左右します。 この記事のパターンをベースに、 あなたのアプリに最適な同期アーキテクチャを構築してみてください。

前のページ  次のページ